﻿using Earthwatchers.Data;
using Earthwatchers.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Principal;
using System.Web;

namespace Earthwatchers.Services.Security
{
    public static class Session
    {
        public const string TOKENKEY = "authtoken";
        public const string secretKey = "clavesecreta";

        public static string GenerateCookie(Earthwatcher ew)
        {
            string compositeToken = Guid.NewGuid().ToString();
            string compositeEwName = ew.Name;
            string compositeEwRole = string.Join(",", ew.GetRoles());
            string composite = string.Format("{0}|{1}|{2}", compositeToken, compositeEwName, compositeEwRole);

            string strToken = TextEncrytion.EncryptString(composite, secretKey);

            //adjuntar cookie
            if (HttpContext.Current.Request.Cookies[Session.TOKENKEY] == null)
            {
                HttpCookie cookie = new HttpCookie(Session.TOKENKEY);
                cookie.Value = strToken;
                DateTime expireDate = DateTime.Now.AddDays(15);
                cookie.Expires = expireDate;
                cookie.HttpOnly = false;
                HttpContext.Current.Response.Cookies.Add(cookie);
            }

            return strToken;
        }

        public static CookieInfo GetCookieInfo()
        {
            CookieInfo info = new CookieInfo();

            try
            {
                HttpCookie cookie = System.Web.HttpContext.Current.Request.Cookies[TOKENKEY];
                if (cookie == null) return info;

                string cookieCompositeValue = cookie.Value;
                string composite = TextEncrytion.DecryptString(cookieCompositeValue, secretKey);
                string[] compositeValues = composite.Split('|');

                info.LoginToken = new Guid(compositeValues[0]);
                info.EarthwatcherName = compositeValues[1];
                info.Roles = compositeValues[2].Split(',');
            }
            catch
            {
            }

            return info;
        }

        public static bool HasLoggedUser()
        {
            return (!string.IsNullOrEmpty(GetCookieInfo().EarthwatcherName));
        }

        public class CookieInfo
        {
            public Guid LoginToken { get; set; }
            public DateTime LoginDateTime { get; set; }
            public string EarthwatcherName { get; set; }
            public string[] Roles { get; set; }
        }


        //public static IPrincipal GetCurrentPrincipal()
        //{
        //    var connectionstring = System.Configuration.ConfigurationManager.ConnectionStrings["EarthwatchersConnection"].ConnectionString;
        //    var ewRepo = new EarthwatcherRepository(connectionstring);
        //    var ew = 
        //}
    }

    public static class TextEncrytion
    {
        public static string EncryptString(string Message, string Passphrase)
        {
            byte[] Results;
            System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();

            // Step 1. We hash the passphrase using MD5
            // We use the MD5 hash generator as the result is a 128 bit byte array
            // which is a valid length for the TripleDES encoder we use below

            System.Security.Cryptography.MD5CryptoServiceProvider HashProvider = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));

            // Step 2. Create a new TripleDESCryptoServiceProvider object
            TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();

            // Step 3. Setup the encoder
            TDESAlgorithm.Key = TDESKey;
            TDESAlgorithm.Mode = CipherMode.ECB;
            TDESAlgorithm.Padding = PaddingMode.PKCS7;

            // Step 4. Convert the input string to a byte[]
            byte[] DataToEncrypt = UTF8.GetBytes(Message);

            // Step 5. Attempt to encrypt the string
            try
            {
                ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor();
                Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length);
            }
            finally
            {
                // Clear the TripleDes and Hashprovider services of any sensitive information
                TDESAlgorithm.Clear();
                HashProvider.Clear();
            }

            // Step 6. Return the encrypted string as a base64 encoded string
            return Convert.ToBase64String(Results);
        }

        public static string DecryptString(string Message, string Passphrase)
        {
            byte[] Results;
            System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();

            // Step 1. We hash the passphrase using MD5
            // We use the MD5 hash generator as the result is a 128 bit byte array
            // which is a valid length for the TripleDES encoder we use below

            System.Security.Cryptography.MD5CryptoServiceProvider HashProvider = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));

            // Step 2. Create a new TripleDESCryptoServiceProvider object
            TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();

            // Step 3. Setup the decoder
            TDESAlgorithm.Key = TDESKey;
            TDESAlgorithm.Mode = CipherMode.ECB;
            TDESAlgorithm.Padding = PaddingMode.PKCS7;

            // Step 4. Convert the input string to a byte[]
            byte[] DataToDecrypt = Convert.FromBase64String(Message);

            // Step 5. Attempt to decrypt the string
            try
            {
                ICryptoTransform Decryptor = TDESAlgorithm.CreateDecryptor();
                Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length);
            }
            finally
            {
                // Clear the TripleDes and Hashprovider services of any sensitive information
                TDESAlgorithm.Clear();
                HashProvider.Clear();
            }

            // Step 6. Return the decrypted string in UTF8 format
            return UTF8.GetString(Results);
        }
    }
}